package 单例模式;

import java.util.concurrent.LinkedBlockingDeque;

/**
 * Created with IntelliJ IDEA.
 * Description:阻塞队列 先用ArrayList实现一个循环队列
 * User: lenovo
 * Date: 2022-09-25
 * Time: 22:29
 */
class MyBlockingQueue{
    //数组
    int[] arr = new int[100];
    //头
    int head = 0;
    //尾
    int tail = 0;
    //计数器
    int size;
    //添加元素
    public void put(int n) throws InterruptedException {
     synchronized (this){
         //先判满,满了阻塞等待
         while(size >= arr.length){//使用while 防止interrupt提前唤醒wait,或者其他线程在wait之前被唤醒又增加了元素导致这里还是满的
             wait();
         }
         arr[tail] = n;
         tail++;
         size++;
         //size++,arr就不为空了,唤醒take里的wait
         notify();
         if(tail >= arr.length){
             tail= 0;
         }
     }
    }
    //删除元素
    public int take() throws InterruptedException {
        synchronized (this){
            //先判空
            while(size == 0){//使用while 防止wait被interrupt的提前唤醒,或者其他线程在wait之前被唤醒,又删除了元素导致这里还是空的
                wait();
            }
            int ret = arr[head];
            head++;
            if(head>= arr.length){
                head=0;
            }
            size--;
            //size--就不满了,唤醒put里的wait
            notify();
            return ret;
        }

    }


}
public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        MyBlockingQueue myBlockingQueue = new MyBlockingQueue();
        Thread t1 = new Thread(()->{
            int n = 1;
            while(true){
                try {
                    myBlockingQueue.put(n);
                    n++;
                    System.out.println("生产元素:"+n);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(()->{
            while (true){
                try {
                    int ret = myBlockingQueue.take();
                    System.out.println("消费元素:"+ ret);
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
        t2.start();
    }


}
